# 实现读取yaml文件的功能
import os
import requests
import json
import copy
import time
import random
import copy
from icon_r_util import read_icon_font_json_dict, read_config, write_error_log, create_icon_svg, chunk_list, read_icon_font_js_to_svg, update_icon_in_codesign, save_icon_svg, read_icon_font_cls_prefix, HEADERS

# 解决 unicode 冲突时的临时开始unicode
CONFLICT_TEMP_UNICODE = 70000
config = read_config()
icon_font_config = config['icon_font']
codesign_config = config['codesign']


def update_icon_unicode(icon_id,  class_name, json_icon_unicode_dict):
    '''
    更新icon的unicode
    '''
    unicode = json_icon_unicode_dict.get(class_name)
    if unicode is None:
        raise Exception('没有找到{}的unicode'.format(class_name))
    unicode = unicode['unicode_decimal']
    update_dict = {
        'unicode': unicode,
    }
    response = update_icon_in_codesign(icon_id, update_dict)
    return response


def send_icons_to_server(json_data, json_icon_unicode_dict: dict,cls_prefix:str):
    '''
    将icon上传到codeisgn服务器
    '''
    request_url = codesign_config['request_url']
    request_method = codesign_config['request_method']
    request_method = request_method.lower()
    unicode_sync = codesign_config['unicode_sync']

    if unicode_sync is True:
        update_request_url = codesign_config.get('update_request_url', None)
        update_request_method = codesign_config.get(
            'update_request_method', None)
        if update_request_url is None or update_request_method is None:
            # 抛出异常
            raise Exception(
                '同步unicode时，必须配置update_request_url和update_request_method')

    # 发送请求
    response = requests.request(
        request_method, request_url, headers=HEADERS, data=json_data)
    # 获取响应状态码
    status_code = response.status_code
    if status_code == 401:
        write_error_log("token失效无权限访问")
        print('token失效无权限访问,请重新登录后再次依照README.md中指引填写token')
        return 'token失效无权限访问'
    # 获取响应数据
    response_data = response.json()
    status_code = response.status_code
    # 合并response_data为一个逗号间隔字符串

    # 判断响应状态码
    if status_code == 200:
        # 如果返回数据中有error字段和message字段则表示上传失败 输出错误信息
        if 'errors' in response_data and 'message' in response_data:
            error_message = {
                "message": response_data['message'],
                "repeated_icon_class_name": [i['class-name'] for i in response_data['repeated_icons']]
            }
            print(error_message)
            write_error_log(json.dumps(error_message))
            return response_data['message']
        class_list_str = ','.join(
            map(lambda x: x['class_name'], response_data))
        if unicode_sync is True:
            will_changed_unicode_list = list(
                map(lambda x: json_icon_unicode_dict.get(x['class_name']), response_data))
            # 有冲突icon列表
            conflict_update_batch_icon_list = list(filter(
                lambda x: will_changed_unicode_list.count(x['unicode']) > 0, response_data))
            # 有冲突的unicode列表
            conflict_update_batch_unicode_list = list(
                map(lambda x: x['unicode'], conflict_update_batch_icon_list))
            if len(conflict_update_batch_unicode_list) > 0:
                print('有冲突的unicode列表：{}'.format(
                    '.'.format(conflict_update_batch_unicode_list)))
            temp_json_icon_unicode_dict = copy.deepcopy(
                json_icon_unicode_dict)
            # 如果两个列表有相交则先更新一遍冲突的unicode
            for index, icon in enumerate(conflict_update_batch_icon_list):
                # 获取icon的class名称
                class_name = icon['class_name']
                # 拼接获取完整的class_name
                if not cls_prefix is None:
                    class_name = '{}{}'.format(cls_prefix, class_name)
                # 获取icon的id
                icon_id = icon['id']

                temp_json_icon_unicode_dict[class_name]['unicode_decimal'] = CONFLICT_TEMP_UNICODE + index
                # 更新icon的unicode
                update_icon_unicode(icon_id, class_name,
                                    temp_json_icon_unicode_dict)

            for icon in response_data:
                # 获取icon的class名称
                class_name = icon['class_name']
                # 拼接获取完整的class_name
                if not cls_prefix is None:
                    class_name = '{}{}'.format(cls_prefix, class_name)
                # 获取icon的id
                icon_id = icon['id']
                # 更新icon的unicode
                update_icon_unicode(icon_id, class_name,
                                    json_icon_unicode_dict)

        return '[{}]上传成功'.format(class_list_str)
    elif status_code == 422:
        # 如果返回数据中有error字段和message字段则表示上传失败 输出错误信息
        if 'errors' in response_data and 'message' in response_data:
            error_message = {
                "message": response_data['message'],
                "repeated_icon_class_name": [i['repeated_icon'].get('class_name') for i in response_data['repeated_icons']]
            }
            print(error_message)
            write_error_log(json.dumps(error_message, ensure_ascii=False))
            return response_data['message']
        else:
            print('上传失败，错误码：{}'.format(status_code))
            return response_data
    else:
        print('上传失败，错误码：{}'.format(status_code))
        return response_data


def save_icon_to_file(icon, icon_save_path):
    '''
    保存icon到文件
    '''
    icon_without_h_w: dict = icon.copy()
    icon_without_h_w.pop('height')
    icon_without_h_w.pop('width')

    icon_str = create_icon_svg(icon_without_h_w)
    print(icon_str)
    save_icon_svg(icon_str, icon_save_path)


def get_uniq_icon_for_codesign(icon_key_list_dict, icon_data_dict):
    """
    获取到一个不会重复的icon(codeisgn中的icon)
    **svg unicode 重复无法解决**
    ** name、class_name 重复 自动拼接数字**
    codeisgn 重复规则  svg、name、class_name、unicode都不能重复
    """
    for key in icon_data_dict.keys():
        # 判断icon_list这个列表中有没有这个icon
        if key in icon_key_list_dict and icon_key_list_dict[key].count(icon_data_dict[key]) > 0:

            message = {
                'class_name': icon_data_dict['class_name'],
                'name': icon_data_dict['name'],
                'repeat_key': key,
                'auto_result': 'Can\'t solve it. But it will be uploaded to codeisgn.'
            }
            if key in ['name', 'class_name']:
                original_value = icon_data_dict[key]
                while icon_key_list_dict[key].count(icon_data_dict[key]) > 0:
                    icon_data_dict[key] = '{}-1'.format(icon_data_dict[key])
                message['auto_result'] = 'val:[{}]-->[{}]'.format(
                    original_value, icon_data_dict[key])
            print('[{}]icon重复了,详情查看error.log 文件'.format(
                icon_data_dict['class_name']))
            write_error_log(json.dumps(message, ensure_ascii=False))
    return icon_data_dict


def get_icons(icon_list, json_icon_unicode_dict, icon_key_list_dict, cls_prefix):
    """
    获得icon列表 (用于codesign上传的数据)
    """
    batch_icon_list = []
    # 遍历icon列表
    for icon in icon_list:
        # 深度拷贝dict
        icon_without_h_w: dict = copy.deepcopy(icon)
        icon_without_h_w.pop('height')
        icon_without_h_w.pop('width')

        origin_icon_str = create_icon_svg(icon)

        icon_str = create_icon_svg(icon_without_h_w)

        # 获取icon的id
        icon_id = icon['icon_id']
        # 获取icon的unicode
        icon_unicode = json_icon_unicode_dict.get(icon_id)
        icon_name = icon_id
        class_name = icon_id
        # 如果有cls_prefix 则需要将icon_id中的cls_prefix去掉
        if not cls_prefix is None:
            # 仅需要需要将首个cls_prefix去掉 例如 icon-xxx --> xxx icon-icon-xxx --> icon-xxx
            class_name = icon_id.split(cls_prefix, 1)[1]
        if not icon_unicode is None:
            icon_name = icon_unicode.get('name', icon_id)
            icon_unicode = icon_unicode['unicode_decimal']
        # 构建icon保存路径
        # icon_save_path = os.path.join(codesign_out_path, icon_id + '.svg')

        # 保存icon的svg文件
        # save_icon_svg(icon_str, icon_save_path)
        # 构建icon的json数据
        json_data_dict = {
            'name': icon_name,
            'class_name': class_name,
            'unicode': icon_unicode,
            'original_svg': origin_icon_str,
            'svg': icon_str
        }

        json_data_dict = get_uniq_icon_for_codesign(
            icon_key_list_dict, json_data_dict)
        #  menu-城市级别

        for key in icon_key_list_dict.keys():
            icon_key_list_dict[key].append(json_data_dict[key])
        # print(json.dumps(json_data_dict))
        batch_icon_list.append(json_data_dict)
    return batch_icon_list


if __name__ == '__main__':
    js_path = icon_font_config['js_path']
    icon_list = read_icon_font_js_to_svg(js_path, icon_font_config)
    # codesign输出路径
    codesign_out_path = codesign_config['out_path']
    # codesign输出路径不存在则创建
    if not os.path.exists(codesign_out_path):
        # 支持多级目录创建
        os.makedirs(codesign_out_path)
    json_path = icon_font_config['json_path']
    cls_prefix = read_icon_font_cls_prefix(json_path)
    json_icon_unicode_dict = read_icon_font_json_dict(json_path)
    icon_key_list_dict = {
        'svg': [],
        'name': [],
        'class_name': [],
        'unicode': [],
    }
    # 下方有两种方式一种是上传icon到codesign服务器，一种是保存icon到本地
    # 将 icon_list 列表保存到本地
    # for icon in icon_list:
    #     icon_id = icon['icon_id']
    #     icon_save_path = os.path.join(codesign_out_path, 'workflow-or-ai' + icon_id + '.svg')
    #     save_icon_to_file(icon, icon_save_path)

    # 将icon_list列表拆分成20个一组上传
    for i in chunk_list(icon_list, 20):
        batch_icon_list = get_icons(
            i, json_icon_unicode_dict, icon_key_list_dict, cls_prefix)
        # 将列表转换为json
        # codesign的proejctid
        project_id = codesign_config['project_id']
        json_data = {
            'project_id': project_id,
            'icons': batch_icon_list
        }
        json_data = json.dumps(json_data)
        # 发送请求

        response = send_icons_to_server(json_data, json_icon_unicode_dict,cls_prefix)
        print(response)
